# -*- coding:utf-8 -*-
import subprocess,re,multiprocessing,time,os,pymysql,nmap80
from multiprocessing import Pool
def readDB(DBname):
	db = pymysql.connect("113.215.1.161", "root", "root", "mydb", charset="utf8")  # 打开数据库连接
	cursor = db.cursor()  # 使用cursor()方法获取操作游标
	sql = "SELECT * FROM %s" % DBname
	cursor.execute(sql)
	results = cursor.fetchall()
	db.close()
	return results

def updateDB(IP):#[host,lossRate,Time,mon,date]
	IP[1]=str(IP[1])
	IP[2] = str(IP[2])
	db=pymysql.connect("113.215.1.161","root","root","mydb",charset="utf8" )# 打开数据库连接
	cursor = db.cursor()# 使用cursor()方法获取操作游标
	#查询
	sqlFind='SELECT * FROM ten_oc WHERE host="%s"' % IP[0]
	#更新
	sqlupdate='UPDATE ten_oc SET lossRate="%s",time="%s",date="%s" WHERE host="%s"' % (IP[1],IP[2],IP[4],IP[0])
	#插入
	sqlInsert='INSERT INTO ten_oc(host,lossRate,time,mon,date) VALUES ("%s","%s","%s","%s","%s")' % tuple(IP)
	print(sqlFind)
	Find=cursor.execute(sqlFind)
	print("找到%s条记录" % Find)
	if Find==0:#如果库中无次记录
		try:
			cursor.execute(sqlInsert)  # 插入记录
			print(sqlInsert,"成功")
		except:
			print(sqlInsert,"失败")
			db.close()
			return 0
	else:
		try:
			cursor.execute(sqlupdate)#更新记录
			print(sqlupdate,"成功")
		except:
			print(sqlupdate, "失败")
			db.close()
			return 0
	db.close()

#定义端口监控的方法

def tcping80(hostlist):#[host,lossRate,time,mon,port]
	hostlist=list(hostlist)
	count=20
	host=hostlist[0]
	mon=hostlist[3]
	port=hostlist[5]
	#print("正在检测 ",host)
	if mon=="no":
		lossRate=0
		Time=0
		return [host,lossRate,Time,mon]
	tcping = os.popen("tcpping   -x %s %s %s" % (count,host,port)).read()
	open = re.findall("open", tcping)
	timeL = re.findall("\d+\.\d+ ms", tcping)
	lossRate=100-len(open)/count*100
	Time = 0
	for x in timeL:
		x=x.replace("ms","")
		x=x.replace(" ","")
		x=float(x)
		Time=Time+x
	try:
		Time=Time/len(timeL)
	except:
		Time=10000
	#print("延时",timeL,Time)
	#print("丢包率",open,lossRate)
	return  [host,lossRate,Time,mon]


def AVG(LossList):
	sum=0
	if len(LossList)>0:
		for x in LossList:
			sum=sum+x
		avg=sum/len(LossList)
	else:
		avg=0
	return avg
def mailAlert():
	fa = open('/tmp/alert.txt', 'w')
	fa.write(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + '\n')
	fa.close()
	hostList = readDB("ten_oc")
	num = 0
	for x in hostList:#[host,lossRate,time,mon,date,port]
		x=list(x)
		if float(x[1])>=1:
			num = num + 1
			x[1]=float(x[1])
			x[2] = float(x[2])
			f = open('../log/%s检测日志.txt' % time.strftime("%Y-%m-%d", time.localtime()), 'a')
			f.write(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+"\t主机：%s\t%s端口丢包率:\t%.2f%%\t 延迟：\t%.2f ms\n" % (x[0],x[5],x[1],x[2]))
			f.close()
			fa = open('/tmp/alert.txt', 'a')
			fa.write("主机：%s\t%s端口丢包率:\t%.2f%%\t 延迟：\t%.2f ms\n" % (x[0],x[5],x[1],x[2]))
			fa.close()
	if num != 0:  # 丢包率大于5的IP数量不为0，发邮件通告
		os.system('sh  /var/www/html/src/sendalert.sh')

def main():
	nmap80.main()#扫描腾讯OC的80端口
	hostList=readDB("ten_oc")
	hostdict = {}
	looptime=600 #600秒，10分钟
	for x in hostList:
		hostdict[x[0]] = []  # 初始化，存放丢包率
	startTime=time.time()//looptime #获得一个初始的时间戳，每10分钟=（秒/600）
	while True:
		try:
			if startTime!=time.time()//looptime:#时间戳不相同（下一个10分到来）
				mailAlert()
				nmap80.main()
				startTime=time.time()//looptime#更新时间戳
				hostList = readDB("ten_oc")
				hostdict = {}
				#looptime = 30  # 600秒，10分钟
				for x in hostList:
					hostdict[x[0]] = []  # 初始化，存放丢包率
				continue
			else:
				p = Pool(200)
				print("开始检测")
				res=p.map(tcping80,hostList)
				p.close()
				p.join()
				for x in res:#x=[host,lossRate,time,mon]
					hostdict[x[0]].append(x[1])
					print(x[0],hostdict[x[0]])
					x[1]=AVG(hostdict[x[0]])
					print("平均值",x[1])

					x.append(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
					updateDB(x)
					print(x)
				time.sleep(10)
		except:
			break
	p.close()
	p.join()
	for xx in hostList:
		xx = list(xx)
		xx[1] = 100
		xx[2] = 10000
		updateDB(xx)
	os.system('echo "腾讯OC端口监控程序运行中断,请重启" | /bin/mail -s "腾讯OC和对等互联80端口丢包告警"  service@watone.com.cn ')
	os.system('echo "腾讯OC端口监控程序运行中断,请重启" | /bin/mail -s "腾讯OC和对等互联80端口丢包告警"  ganlian@watone.com.cn ')


if __name__ == '__main__':
	main()
